#ifndef _CPP_STORY_CONTEXT_PTR_H_
#define _CPP_STORY_CONTEXT_PTR_H_

#include <stdio.h>
#include "step_definition.h"
#ifdef WIN32
#include "cppstory_win32.h"
#endif

namespace CppStory
{

#ifdef WIN32
class CPPSTORY_WIN32_API ContextPtr
#else
class ContextPtr
#endif
{
public:
    ContextPtr() {}
    virtual ~ContextPtr() {}
    virtual void clean() = 0;
};

template<class T>
class ContextPtrImpl : public ContextPtr
{
public:
    ContextPtrImpl(StepDefinition* step_def);
    T* operator->();
    virtual void clean();
private:
    static T* contextReference;
};

template<class T>
T* ContextPtrImpl<T>::contextReference = NULL;

template<class T>
ContextPtrImpl<T>::ContextPtrImpl(StepDefinition* step_def)
{
    if (NULL == contextReference)
    {
        // ugly, but works.
        // maybe: share_ptr+weak_ptr?
        contextReference = new T();
        ContextPtrImpl<T>* tempContextPtr = new ContextPtrImpl<T>(step_def);
        step_def->register_context_ptr(tempContextPtr);
    }
}

template<class T>
T* ContextPtrImpl<T>::operator->()
{
    return contextReference;
}

template<class T>
void ContextPtrImpl<T>::clean()
{
    if (NULL != contextReference)
    {
        delete contextReference;
        contextReference = NULL;
        delete this;
    }
}

}

#endif

